#pragma once

#include "nlohmann/json.hpp"
#include <string>
#include <fstream>
#include <sstream>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>

namespace PokerBoxSaveInfoServices
{
	class SaveInfoBase
	{
	private:
		bool TrySaveToFile(std::string jsonString)
		{
			if (!access(_fileName.c_str(), 0))
			{
				auto file = fopen(_fileName.c_str(), "w");
				fputs(jsonString.c_str(), file);
				fclose(file);
				return true;
			}

			return false;
		}

	protected:
		std::string _fileName;

		virtual void OnDeserialize(nlohmann::json &json) = 0;
		virtual void OnSerialize(nlohmann::json &json) = 0;

		bool TryGetJsonObject(std::string &jsonFile, nlohmann::json *outObject)
		{
			if (!access(jsonFile.c_str(), 0))
			{
				std::ifstream fs(jsonFile);

				if (fs.is_open())
				{
					std::ostringstream ss;
					ss << fs.rdbuf();
					auto str = ss.str();
					(*outObject) = nlohmann::json::parse(ss.str());

					return true;
				}
			}

			return false;
		}

	protected:
		SaveInfoBase(const char *fileName)
		{
			_fileName = fileName;
		}

	public:
		bool Deserialize()
		{
			nlohmann::json jsonObj;

			if (TryGetJsonObject(_fileName, &jsonObj))
			{
				this->OnDeserialize(jsonObj);
				return true;
			}

			return false;
		}

		bool Serialize()
		{
			nlohmann::json obj;
			this->OnSerialize(obj);
			auto jsonString = obj.dump();
			return TrySaveToFile(jsonString);
		}
	};
}
